package com.lsh.ofc.worker.task;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dangdang.ddframe.job.api.JobExecutionMultipleShardingContext;
import com.lsh.base.common.exception.BusinessException;
import com.lsh.ofc.core.constant.Constants;
import com.lsh.ofc.core.entity.OfcObdDetail;
import com.lsh.ofc.core.entity.OfcObdHead;
import com.lsh.ofc.core.entity.OfcSoHead;
import com.lsh.ofc.core.entity.OfcTask;
import com.lsh.ofc.core.enums.OfcTaskStatus;
import com.lsh.ofc.core.enums.OfcTaskType;
import com.lsh.ofc.core.exception.EC;
import com.lsh.ofc.core.mail.EmailTemplate;
import com.lsh.ofc.core.proxy.service.WumartOfcServiceProxy;
import com.lsh.ofc.core.service.OfcObdService;
import com.lsh.ofc.core.service.OfcSoService;
import com.lsh.ofc.core.service.OfcTaskService;
import com.lsh.ofc.proxy.context.WumartBasicContext;
import com.lsh.ofc.worker.base.AbstractSimpleJob;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.*;

/**
 * Project Name: OfcQueryObdInfoFromWumart
 * 北京链商电子商务有限公司
 * Auth: wangliutao
 * Date: 18/8/16
 * Package Name: com.lsh.ofc.worker.task
 * Description:
 *
 * @author wangliutao
 */
@Component
public class OfcQueryObdInfoFromWumartJob extends AbstractSimpleJob {
    private static final Logger logger = LoggerFactory.getLogger(OfcQueryObdInfoFromWumartJob.class);

    @Autowired
    private OfcTaskService ofcTaskService;

    @Autowired
    private WumartOfcServiceProxy wumartOfcServiceProxy;

    @Autowired
    private OfcSoService ofcSoService;

    @Autowired
    private OfcObdService ofcObdService;

    @Autowired
    private EmailTemplate emailTemplate;

    @Value("${email.default.to}")
    private String receiver;

    @Value("${email.env}")
    private String system;

    @Override
    protected void execute(JobExecutionMultipleShardingContext context) {
        List<OfcTask> tasks = this.getTasks(context);
        if (tasks == null) {
            return;
        }
        logger.info("【Wumart obd query】 fetch data size is {}", tasks.size());

        for (OfcTask task : tasks) {
            logger.info("【Wumart obd query】 task is {}", JSON.toJSONString(task));
            String soBillCode = task.getContent();
            Long orderCode = task.getRefId();

            this.validateAndSendEmail(task);

            try {
                OfcSoHead filter = new OfcSoHead();
                filter.setSoBillCode(soBillCode);
                filter.setOrderCode(orderCode);
                OfcSoHead ofcSoHead = ofcSoService.findOne(filter, false);

                String orderInfo = wumartOfcServiceProxy.queryMeipiOrder(WumartOfcServiceProxy.OrderType.NORMAL, soBillCode,
                        WumartBasicContext.buildContext(ofcSoHead.getRegionCode(), ofcSoHead.getSupplierCode(), ofcSoHead.getSupplierOrg(), ofcSoHead.getSupplierId(), ofcSoHead.getSupplierGroup()));

                this.processOrderInfo(ofcSoHead, orderInfo);

                this.ofcTaskService.updateTask(task, true);
            } catch (Exception e) {
                logger.error("【Wumart obd query】 Error! orderCode is " + orderCode, e);
                this.ofcTaskService.updateTask(task, false);
            }
        }
    }

    private void processOrderInfo(OfcSoHead ofcSoHead, String content) {
        JSONObject orderInfo = JSON.parseObject(content);

        String billCode = orderInfo.getString("billCode");
        if (!ofcSoHead.getSoBillCode().equals(billCode)) {
            throw new BusinessException(EC.ERROR_PARAMS.getCode(), "订单号不匹配");
        }

        JSONObject obdInfo = orderInfo.getJSONObject("obdInfo");
        if (obdInfo == null) {
            throw new BusinessException(EC.ERROR_PARAMS.getCode(), "obdInfo 为空");
        }

        JSONArray details = obdInfo.getJSONArray("details");
        if (details == null || details.size() == 0) {
            throw new BusinessException(EC.ERROR_PARAMS.getCode(), "details 为空");
        }

        OfcObdHead ofcObdHead = this.buildOfcObdHead(obdInfo, ofcSoHead, details);

        logger.info("【Wumart obd query】 create ofcObdHead start! orderCode is {}", ofcSoHead.getOrderCode());
        ofcObdService.create(ofcObdHead, true, true);
        logger.info("【Wumart obd query】 create ofcObdHead end!");
    }

    private OfcObdHead buildOfcObdHead(JSONObject obdInfo, OfcSoHead ofcSoHead, JSONArray items) {
        BigDecimal totalSkuQty = BigDecimal.ZERO;
        List<OfcObdDetail> details = new ArrayList<>(items.size());
        for (int i = 0; i < items.size(); i++) {
            JSONObject item = items.getJSONObject(i);
            logger.info("【Wumart obd query】 item: {}", item);

            JSONObject json = new JSONObject();
            json.put(Constants.OBD_D_PACK_NUM, "");
            json.put(Constants.OBD_D_BOX_NUM, "");
            json.put(Constants.OBD_D_LEFT_EA_NUM, "");

            BigDecimal skuQty = item.getBigDecimal("skuQty");
            String skuSupplyCode = item.getString("skuCode");

            OfcObdDetail detail = new OfcObdDetail();
            detail.setSkuSupplyCode(skuSupplyCode);
            detail.setSkuDeliverQty(skuQty);
            detail.setExt(json.toJSONString());
            details.add(detail);
            totalSkuQty = totalSkuQty.add(skuQty);
        }

        JSONObject json = new JSONObject();
        json.put(Constants.OBD_H_CREATE_TIME, ObjectUtils.toString(obdInfo.getString("createTime")));
        json.put(Constants.OBD_H_DELIVERY_TIME, ObjectUtils.toString(obdInfo.getString("deliveryTime")));

        OfcObdHead obd = new OfcObdHead();
        obd.setSoBillCode(ofcSoHead.getSoBillCode());
        obd.setRegionCode(ofcSoHead.getRegionCode());
        //物美EWM
        obd.setFulfillWms(1);
        obd.setSoCode(obdInfo.getString("soCode"));
        String obdCode = obdInfo.getString("obdCode");
        if (StringUtils.isBlank(obdCode)) {
            obdCode = "-1";
        }
        obd.setObdCode(obdCode);
        obd.setTotalSkuDeliverQty(totalSkuQty);
        obd.setExt(json.toJSONString());
        obd.setDetails(details);

        return obd;
    }

    private void validateAndSendEmail(OfcTask task) {
        try {
            if (task.getExecCount() != 0 && task.getExecCount() % 20 == 0) {
                logger.info("【Wumart obd query】task's execCount: {}, send email", task.getExecCount());
                StringBuilder emailContent = new StringBuilder("【OfcQueryObdInfoFromWumartJob任务】");
                emailContent.append("\n").append("从物美查询OBD信息第")
                        .append(task.getExecCount()).append("次，task：")
                        .append("\n").append(JSON.toJSONString(task));
                this.emailTemplate.send("【" + system + "】【PC-查询物美OBD信息第" + task.getExecCount() + "次】", new String[]{receiver}, emailContent.toString());
            }
        } catch (Exception e) {
            logger.error("【Wumart obd query】send email failed!!");
        }

    }

    private List<OfcTask> getTasks(JobExecutionMultipleShardingContext context) {
        Set<OfcTaskStatus> status = new HashSet<>();
        status.add(OfcTaskStatus.NEW);
        status.add(OfcTaskStatus.ERROR);
        return ofcTaskService.fetchTasks(OfcTaskType.OBD_QUERY, status, 20, null);
    }
}
